package cn.richard.demo.ruleengine.config;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.mvel.MVELRule;
import org.springframework.stereotype.Component;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.richard.demo.ruleengine.util.MyRulesUtil;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class RuleFireService {
	@Resource
	private NacosConfigExChannelRule exChannelRuleConfig;
	@Resource
	private RulesEngine ruleEngine;
	
	private Rules rules = new Rules();
	
	private static final Object PRESENT = new Object(); //模仿 HashSet
	
	@PostConstruct
	private void initRules() {
		log.info(">> load rules");
		exChannelRuleConfig.getRules().forEach(o -> {
        	rules.register(new MVELRule().name(o.getName())
        								 .description(o.getDescription())
        								 .priority(o.getPriority())
        								 .when(o.getCondition())
        								 .then(getActions(o.getActions())));
        });
		log.info("<< load rules, rules size: {}", MyRulesUtil.countRules(rules));
	}
	
	/**
	 * 执行规则
	 * 
	 * @param elName 规则语句中的EL对象的key
	 * @param obj 需要修改状态的对象
	 */
	public void fire(String elName, Object obj) {
		Assert.notBlank(elName);
		Assert.notNull(obj);
		synchronized (PRESENT) {
			Facts facts = new Facts();
			facts.put(elName, obj);
			ruleEngine.fire(rules, facts);
		}
	}
	
	public void refreshRules() {
		log.info(">> refresh rules");
		synchronized (PRESENT) {
			//log.debug("222");
			rules.clear();
			initRules();
		}
		log.info("<< refresh rules");
	}
	
	private String getActions(List<String> actions) {
		StringBuilder sb = new StringBuilder();
		if(CollUtil.isNotEmpty(actions)) {
			actions.forEach(sb::append);
		}
		return sb.toString();
	}
}
